<template>
  <div style="width: 100%; height: 100%; position: relative; display: flex; flex-direction: column">
    <div :id="videoId" class="easy-player" />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import request from '@/utils/request';

const props = defineProps({
  id: {
    type: [Number, String],
    default: '',
    required: true
  },
  url: {
    type: [String],
    default: '',
    required: true
  },
  showVideoControl: {
    type: [Boolean],
    default: false
  }
});
const emit = defineEmits(['openCameraControl']);

const { proxy } = getCurrentInstance() as ComponentInternalInstance;

let easyPlayer = reactive({});
const easyPlayerConfig = reactive({ isNotMute: true, hasAudio: true });
const videoId = ref(Math.floor(Math.random() * 10000000000));
const timer = ref();
const kBpsSum = ref(0);
const playError = ref(false);
const videoContainer = ref();
const stretchEl = ref();

const playCreate = () => {
  videoContainer.value = document.getElementById(videoId.value);
  easyPlayer = new EasyPlayerPro(videoContainer.value, {
    isResize: false,
    useMSE: true,
    useWCS: true,
    hasAudio: easyPlayerConfig.hasAudio,
    isNotMute: easyPlayerConfig.isNotMute
  });
  easyPlayer.play(props.url).then(() => {
    console.log('视频加载成功')

    //  静音
    easyPlayer.setMute(true)
  }).catch((e) => {
    console.error('视频播放错误：', e);
    playError.value = true
  });

  easyPlayer.on('error', function (err) {
    console.error('播放失败：', err)
    playError.value = true
  })
  easyPlayer.on('play', function () {
    console.log('播放事件')

    //  初始化按钮
    initBtn()
  })
  easyPlayer.on('liveEnd', function () {
    console.log('直播结束')
  })
  easyPlayer.on('fullscreen', function (flag) {
    console.log('是否全屏：', flag)
  })
  easyPlayer.on('decodeHevc', function (val) {
    console.log('视频编码：', val)
  })
  easyPlayer.on('kBps', function (val) {
    // console.log('当前网速：', val)
    kBpsSum.value += Number(val) || 0
  })
  easyPlayer.on('screenshots', function (val) {
    console.log('截图：', val)
  })
  easyPlayer.on('videoInfo', function (val) {
    console.log('视频信息：', val)

    //  初始化按钮
    initBtn()
  })

  clearInterval(timer.value)
  timer.value = setInterval(() => {
    //  视频成功加载完成后，删除定时器
    if (kBpsSum.value > 0) {
      clearInterval(timer.value)
    }

    //  视频加载失败，或在一定时间内没有加载成功，显示加载失败图标，并删除定时器
    let easyPlayerLoadingEl = videoContainer.value.querySelector('.easyplayer-loading')
    if (playError.value == true || (easyPlayerLoadingEl.style.display == 'none' && kBpsSum.value == 0)) {
      easyPlayerLoadingEl.style.setProperty('display', 'flex', 'important')
      videoContainer.value.querySelector('.easyplayer-loading-img').style.setProperty('background-image', 'url("/src/assets/icons/svg/video-fail-fill.svg")', 'important')

      clearInterval(timer.value)
    }
  }, 1000);
}

const openCameraControl = () => {
  emit('openCameraControl', { equipmentId: props.id, url: props.url });
};

/**
 * 静音
 */
const setMute = ()=> {
  console.log('静音：', easyPlayer.isMute())
  easyPlayer.setMute(!easyPlayer.isMute())
}

/**
 * 是否静音
 */
const isMute = ()=> {
  return easyPlayer.isMute()
}

/**
 * 抓拍
 */
const screenShot = async () => {
  let easyPlayerLoadingEl = videoContainer.value.querySelector('.easyplayer-tips-message')
  easyPlayerLoadingEl.style.setProperty('display', 'block', 'important')
  videoContainer.value.querySelector('.easyplayer-tips-message-content').innerHTML = '<div style="width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; font-size: 16px; color: #fff;">正在抓拍...</div>'

  let videoPlayerElement = document.getElementById(videoId.value)
  let videoElement = videoPlayerElement.querySelector('video');

  //  图片裁剪画布
  let canvas = document.createElement('canvas');
  canvas.id = 'canvas-' + Math.floor(Math.random() * 100000000);
  canvas.width = videoElement.videoWidth;
  canvas.height = videoElement.videoHeight;
  canvas.style.display = 'none';
  //  图片裁剪画笔
  let canvas2d = canvas.getContext('2d');

  canvas2d.drawImage(
    videoElement,
    0, //  源图像中裁剪区域的起始 x 坐标（水平方向的起始点）。
    0, //  源图像中裁剪区域的起始 y 坐标（垂直方向的起始点）。
    canvas.width, //  裁剪区域的宽度。
    canvas.height, //  裁剪区域的高度。
    0, //  目标 Canvas 上绘制区域的起始 x 坐标。
    0, //  目标 Canvas 上绘制区域的起始 y 坐标。
    canvas.width, //  绘制到 Canvas 上的图像的宽度。
    canvas.height //  绘制到 Canvas 上的图像的高度。
  );

  canvas.toBlob((res)=> {
    if (!res) {
      proxy?.$modal.msgError('抓拍失败');
      easyPlayerLoadingEl.style.setProperty('display', 'none')

      return
    }

    let file = new File([res], Math.floor(Math.random() * 1000000000) + '.png', { type: res.type });
    const formData = new FormData();
    formData.append('file', file);

    //  上传文件到OSS
    request({
      url: '/resource/oss/upload',
      method: 'post',
      data: formData
    }).then((upRes) => {
      console.log('上传文件：', upRes)

      //  添加媒体库
      request({
        url: '/camera/media_info',
        method: 'post',
        data: { fileId: upRes.data.ossId, equipmentId: props.id }
      }).then((mediaRes) => {
        console.log('添加媒体库：', mediaRes)

        proxy?.$modal.msgSuccess('抓拍成功');
        videoContainer.value.querySelector('.easyplayer-tips-message-content').innerHTML = '<div style="width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; font-size: 16px; color: #3ac35c;">抓拍成功</div>'
      }).catch((err) => {
        videoContainer.value.querySelector('.easyplayer-tips-message-content').innerHTML = '<div style="width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; font-size: 16px; color: #ff0000;">抓拍失败</div>'
        //  2秒后隐藏提示信息
        setTimeout(()=> {
          easyPlayerLoadingEl.style.setProperty('display', 'none')
        }, 2000)
      }).finally(()=> {
        //  2秒后隐藏提示信息
        setTimeout(()=> {
          easyPlayerLoadingEl.style.setProperty('display', 'none')
        }, 2000)
      });
    }).catch((err) => {
      videoContainer.value.querySelector('.easyplayer-tips-message-content').innerHTML = '<div style="width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; font-size: 16px; color: #ff0000;">抓拍失败</div>'
      //  2秒后隐藏提示信息
      setTimeout(()=> {
        easyPlayerLoadingEl.style.setProperty('display', 'none')
      }, 2000)
    });
  });
};

/**
 * 初始化按钮
 */
const initBtn = () => {
  /* 视频宽高切换成标准比率 */
  if (stretchEl.value) {
    stretchEl.value.click()
  }

  /* 切图 */
  let customScreenshotEl = videoContainer.value.querySelector('.easyplayer-screenshot-custom')
  if (!customScreenshotEl) {
    let screenshotEl = videoContainer.value.querySelector('.easyplayer-controls-item-wrap .easyplayer-screenshot')
    screenshotEl.parentNode.style.position = 'relative'
    customScreenshotEl = document.createElement('div');
    customScreenshotEl.className = 'easyplayer-screenshot-custom'
    screenshotEl.before(customScreenshotEl)
    screenshotEl.parentNode.appendChild(customScreenshotEl)
    customScreenshotEl.addEventListener('click', ()=> {
      screenShot()
    });
  }

  /* 全屏按钮打开视频控制台 */
  if (props.showVideoControl) {
    let customFullscreenEl = videoContainer.value.querySelector('.easyplayer-fullscreen-custom')
    if (!customFullscreenEl) {
      let fullscreenEl = videoContainer.value.querySelector('.easyplayer-controls-item-wrap .easyplayer-fullscreen')
      fullscreenEl.parentNode.style.position = 'relative'
      customFullscreenEl = document.createElement('div');
      customFullscreenEl.className = 'easyplayer-fullscreen-custom'
      fullscreenEl.parentNode.appendChild(customFullscreenEl)
      customFullscreenEl.addEventListener('click', ()=> {
        openCameraControl()
      });
    }
  }
}

onMounted(() => {
  playCreate()
});
onBeforeUnmount(() => {
  // 销毁定时器
  clearInterval(timer.value)

  // 销毁播放器
  if (easyPlayer) {
    easyPlayer.destroy()
    easyPlayer = {}
  }
});

defineExpose({ screenShot, setMute, isMute })
</script>

<style lang="scss" scoped>
.easy-player {
  display: block;
  width: 100%;
  //height: calc(100% - 30px);
  height: 100%;
}
.video-control {
  height: 30px;
  position: absolute;
  bottom: 0;
  right: 10px;
  display: flex;
  align-items: center;
  .video-control-item {
    position: relative;
    cursor: pointer;
    margin: auto 16px;
    height: 18px;
    width: 18px;
    display: flex;
    justify-content: center;
    align-items: center;
    .bias {
      z-index: 99;
      position: absolute;
      height: 120%;
      width: 2px;
      background-color: #767676;
      transform: rotate(45deg);
    }
  }
}
:deep(.easy-player .easyplayer-controls) {
  //display: none;
}
:deep(.easy-player .easyplayer-loading) {
  z-index: 1 !important;
  .easyplayer-loading-img {
    height: 200px;
    background-image: url("/src/assets/images/video-loading.gif")  !important;
  }
}
:deep(.easy-player .easyplayer-controls) {
  opacity: 1 !important;
}

:deep(.easyplayer-screenshot-custom:hover + .easyplayer-screenshot) {
  .icon-title-tips {
    visibility: visible;
    opacity: 1;
  }
}
:deep(.easyplayer-fullscreen-custom:hover + .easyplayer-fullscreen) {
  .icon-title-tips {
    visibility: visible;
    opacity: 1;
  }
}
:deep(.easyplayer-screenshot-custom) {
  position: absolute;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  cursor: pointer;
}
:deep(.easyplayer-fullscreen-custom) {
  position: absolute;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  cursor: pointer;
}
video {
  z-index: 1;
}
:deep(.easyplayer-tips-message .easyplayer-tips-message-close .easyplayer-tips-message-close-icon) {
  background-color: #b8b9b8;
  align-self: center;
  cursor: pointer;
}
:deep(.easyplayer-tips-message:before) {
  //content: "X";
  content: "";
}

</style>
